package com.shadowtorcher.stdisk.logic;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.shadowtorcher.soulknife.SoulKnifeDB;
import com.shadowtorcher.soulknife.exception.BeanConfigErrorException;
import com.shadowtorcher.soulknife.util.Logger;
import com.shadowtorcher.stdisk.bean.CdnBean;
import com.shadowtorcher.stdisk.bean.CdnFileBean;
import com.shadowtorcher.stdisk.bean.PhysicsFileBean;
import com.shadowtorcher.stdisk.util.StaticUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;


public class FileSender {
    private PhysicsFileBean physicsFileBean;
    private File file;

    public FileSender(PhysicsFileBean fileBean, File file) {
        this.physicsFileBean = fileBean;
        this.file = file;
    }

    public void send() {
        try {
            List<CdnBean> cdnBeans = SoulKnifeDB.selectAll().setClass(CdnBean.class);
            for (CdnBean cdnBean : cdnBeans) {
                String url = cdnBean.getCdnUrl() + "/upload/" + physicsFileBean.getPhysicsFileID();
                Logger.logD("get cdn url: " + url);
                new Thread(() -> {
                    try {
                        if (sendFile(url, file)) {
                            CdnFileBean cdnFileBean = new CdnFileBean();
                            cdnFileBean.setCdnId(cdnBean.getCdnId());
                            cdnFileBean.setPhysicsFileID(physicsFileBean.getPhysicsFileID());
                            cdnFileBean.save();
                            file.delete();
                        }
                    } catch (BeanConfigErrorException | IOException | SQLException e) {
                        e.printStackTrace();
                    }
                }).start();
            }
        } catch (SQLException | BeanConfigErrorException e) {
            e.printStackTrace();
        }
    }

    private boolean sendFile(String url, File file) throws IOException {
        Logger.logD("sending " + url);
        String boundary = StaticUtils.generatorStringUUID();
        HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
        try {
            urlConnection.setDoOutput(true);
            urlConnection.setRequestMethod("POST");
            urlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
            urlConnection.setRequestProperty("User-Agent", "dragons-treasure-client-0.1");

            OutputStream outputStream = urlConnection.getOutputStream();
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream), true);

            String CRLF = "\r\n";
            writer.append("--").append(boundary).append(CRLF);
            writer.append("Content-Disposition: form-data; name=\"data\"; filename=\"data\"").append(CRLF);
            writer.append("Content-Type: application/octet-stream").append(CRLF);
            writer.append(CRLF).flush();

            Files.copy(file.toPath(), outputStream);
            outputStream.flush();
            writer.append(CRLF).flush();

            writer.append("--").append(boundary).append("--").append(CRLF).flush();
        } catch (Exception e) {
            e.printStackTrace();
        }

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8));
        Map<String, String> response = (new Gson()).fromJson(bufferedReader, new TypeToken<Map<String, String>>() {
        }.getType());
        urlConnection.disconnect();
        switch (response.get("state")) {
            case "success":
                return true;
            case "failure":
                Logger.logE(response.get("why"));
                return false;
            default:
                Logger.logE("未知错误");
                return false;
        }
    }
}